package util

import (
	"Graphite/database"
	"context"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
	"log"
)

//searchKey字段已有的内容的不可重复增加接口

func CreateOne(c *gin.Context,collection string,data interface{},searchKey string,value string)  {
	Collection := database.DB.Collection(collection)
	var one bson.M
	var One interface{}
	err := Collection.FindOne(context.Background(), bson.M{searchKey: value}).Decode(&one)
	if err != nil {
		One = data
		insertOneResult, err := Collection.InsertOne(context.Background(), One)
		if err != nil {
			Return(c,200,EXCEPTION,err)
			log.Println(err)
		}
		log.Println("collection.InsertOne: ", insertOneResult.InsertedID)
		Return(c,200,SUCCESS,insertOneResult)
	}else {
		Return(c,200,HAS_EXIST,one)
		return
	}
}




//单字段模糊搜索查找接口

func Retrieve(c *gin.Context,collection string,searchKey string,value string) []byte {
	Collection := database.DB.Collection(collection)
	//cur, err := Collection.Find(context.Background(), bson.M{searchKey: primitive.Regex{Pattern: value}})
	cur, err := Collection.Find(context.Background(), bson.M{searchKey:  primitive.Regex{Pattern: value}})
	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	if err := cur.Err(); err != nil {
		log.Println(err)
	}
	var all []bson.M
	err = cur.All(context.Background(), &all)
	if err != nil {
		log.Println(err)
	}
	_:cur.Close(context.Background())
	//log.Println("collection.Find curl.All: ", all)
	for _, one := range all {
		log.Println(one)
	}
	jsonStr, err := json.Marshal(all)
	return jsonStr
}
func RetrieveP(c *gin.Context,collection string,searchKey string,value string,page int64, perPage int64) ([]byte, int64) {
	Collection := database.DB.Collection(collection)
	var findOptions *options.FindOptions
	findOptions =&options.FindOptions{}
	findOptions.SetLimit(perPage)             //每页数据数量
	findOptions.SetSkip(perPage * (page - 1)) //根据第几页跳过数据
	total,err:= Collection.CountDocuments(context.Background(),bson.M{searchKey:primitive.Regex{Pattern: value}})
	cur, err := Collection.Find(context.Background(), bson.M{searchKey:  primitive.Regex{Pattern: value}},findOptions)
	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	if err := cur.Err(); err != nil {
		log.Println(err)
	}
	var all []bson.M
	err = cur.All(context.Background(), &all)
	if err != nil {
		log.Println(err)
	}
	_:cur.Close(context.Background())
	//log.Println("collection.Find curl.All: ", all)
	/*for _, one := range all {
		log.Println(one)
	}*/
	jsonStr, err := json.Marshal(all)
	return jsonStr,total
}

//多字段模糊搜索

func Retrieves(c *gin.Context, collection string, searchKey1 string, searchKey2 string, value string,page int64) ([]byte, int64) {
	Collection := database.DB.Collection(collection)
	var findOptions *options.FindOptions
	findOptions =&options.FindOptions{}
	findOptions.SetLimit(10)            //每页数据数量
	findOptions.SetSkip(10 * (page - 1)) //根据第几页跳过数据
	total,err:= Collection.CountDocuments(context.Background(),bson.M{searchKey1:primitive.Regex{Pattern:value},searchKey2:primitive.Regex{Pattern:value}})
	//cur, err := Collection.Find(context.Background(), bson.M{searchKey: primitive.Regex{Pattern: value}})
	cur,err := Collection.Find(context.Background(),bson.M{"$or":[]bson.M{
		{searchKey1:primitive.Regex{Pattern:value}},{searchKey2:primitive.Regex{Pattern:value}}}},findOptions)

	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	if err := cur.Err(); err != nil {
		log.Println(err)
	}
	var all []bson.M
	err = cur.All(context.Background(), &all)
	if err != nil {
		log.Println(err)
	}
	_:cur.Close(context.Background())
	//log.Println("collection.Find curl.All: ", all)
	for _, one := range all {
		log.Println(one)
	}
	jsonStr, err := json.Marshal(all)
	return jsonStr,total

}

func RetrievesAnd(c *gin.Context, collection string, searchKey1 string, searchKey2 string,searchKey3 string, value1 string,value3 string, page int64,perPage int64) ([]byte,int64) {
	Collection := database.DB.Collection(collection)
	var filter = bson.M{"$or":[]bson.M{
		{searchKey1:primitive.Regex{Pattern:value1},searchKey3:primitive.Regex{Pattern:value3}},{searchKey2:primitive.Regex{Pattern:value1},searchKey3:primitive.Regex{Pattern:value3}}}}
	//var findOptions *options.FindOptions
	findOptions :=&options.FindOptions{}
	findOptions.SetLimit(perPage)            //每页数据数量
	findOptions.SetSkip(perPage * (page - 1))
	total,err:= Collection.CountDocuments(context.Background(),filter)
	cur,err := Collection.Find(context.Background(),filter,findOptions)

	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	if err := cur.Err(); err != nil {
		log.Println(err)
	}
	var all []bson.M
	err = cur.All(context.Background(), &all)
	if err != nil {
		log.Println(err)
	}
_:cur.Close(context.Background())
	//log.Println("collection.Find curl.All: ", all)
	//for _, one := range all {
	//	log.Println(one)
	//}
	jsonStr, err := json.Marshal(all)
	return jsonStr,total

}



//根据ID进行单个删除接口

func DeleteOne(c *gin.Context,collection string,deleteKey string,value primitive.ObjectID )  {
	Collection := database.DB.Collection(collection)
	deleteResult, err := Collection.DeleteOne(context.Background(), bson.M{deleteKey:value})
	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	Return(c,200,SUCCESS,deleteResult)
}

//根据ID进行单个更新接口

func UpdateOne(c *gin.Context,collection string,data interface{},searchKey string,value primitive.ObjectID )  {
	Collection := database.DB.Collection(collection)
	update := bson.M{"$set": data}
	//fmt.Println("data:",data,"value:",value)
	updateResult, err := Collection.UpdateOne(context.Background(), bson.M{searchKey:value}, update)
	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	log.Println("collection.UpdateOne:", updateResult)
	Return(c,200,SUCCESS,data)
}

//根据ID进行单个更新接口---不返回信息

func UpdateOne1(c *gin.Context,collection string,data interface{},searchKey string,value primitive.ObjectID )  {
	Collection := database.DB.Collection(collection)
	update := bson.M{"$set": data}
	//fmt.Println("data:",data,"value:",value)
	updateResult, err := Collection.UpdateOne(context.Background(), bson.M{searchKey:value}, update)
	if err != nil {
		Return(c,200,EXCEPTION,err)
		log.Println(err)
	}
	log.Println("collection.UpdateOne:", updateResult)
}

func In (search string, strArray []string) bool {
	for _, element := range strArray{
		if search == element{
			return true
		}
	}
	return false
}




